#include "MetalBox.h"
#include "Camera.h"
#include "Time.h"
#include "WoodBox.h"
#include "IceBlock.h"
#include "IceLayer.h"
#include "Water.h"
#include "Events\Event.h"
#include "Events\CSGD_EventSystem.h"

#include "GamePlayState.h"

// Constructor
MetalBox::MetalBox(void)
{
	objectID = "Metal Box";

	canFall = true;
	this->SetCoolRate(1.0f);
}

// Destructor
MetalBox::~MetalBox(void)
{
}

void MetalBox::Update(float deltaTime)
{
	if(canFall == true)
		this->positionY += Physics::GetGravity() * Time::GetInstance().DeltaTime();

	Physics::UpdateColRect(hitBox, (int)positionX, (int)positionY);

	//Check below the box. If there is nothing below the box apply gravity
	float BoxHeight = (float)hitBox.bottom - hitBox.top;
	float BoxWidth = (float)hitBox.right - hitBox.left;

	//Calculate Center
	tVector2D BoxCenter = { BoxWidth * 0.5f + hitBox.left, hitBox.bottom + 1.0f };

	//Direction 
	tVector2D CheckBottomCastDirection = { 0, 1 };

	//Info to fill out
	LinecastInfo CheckBottomInfo;

	//Check Line Cast
	//if(canFall = true)
	{
		//canFall = Physics::LineCast( CheckBottomInfo, 2, BoxCenter, CheckBottomCastDirection, "Button" ) ? false : true; 
		//if(Time::GetInstance().TotalFrames() % 10 == 0)
		{
			canFall = true;
		}
	}

	HeatPhysics::Update(deltaTime);
}
void MetalBox::Render(void) const
{
	CSGD_TextureManager::GetInstance()->Draw(imageID, 
		(int)(positionX - Camera::GetInstance()->OffsetX()),
		(int)(positionY - Camera::GetInstance()->OffsetY()), 1.0f,1.0f,
		0, 0.0f, 0.0f,0.0f);

	//Render hit box
	RECT box = GetHitBox();
	box.left = (int)(box.left - Camera::GetInstance()->OffsetX());
	box.right = (int)(box.right - Camera::GetInstance()->OffsetX());
	box.bottom = (int)(box.bottom - Camera::GetInstance()->OffsetY());
	box.top = (int)(box.top - Camera::GetInstance()->OffsetY());
	CSGD_Direct3D::GetInstance()->DrawRect(box,GetColorFromTemp());
}
void MetalBox::HandleCollision(GameObject& other, CollisionInfo& info)
{
	if(GamePlayState::GetInstance()->GetPlayer()->GetToolManager()->GetMag().GetAttched() == this)
		return;

	if(other.GetObjectID() == "Metal Box" || other.GetObjectID() == "Wood Box" || other.GetObjectID() == "Radiation Barrel")
	{
		int amtToMove;
		switch( info.Side )
		{
		case LEFT:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		case RIGHT:
			amtToMove = info.Overlap.right - info.Overlap.left;
			other.Push( info.Side, amtToMove );
			break;
		case TOP:
			amtToMove = info.Overlap.bottom - info.Overlap.top;
			other.Push( info.Side, amtToMove );
			break;
		case BOTTOM:
			amtToMove = info.Overlap.bottom - info.Overlap.top;
			other.Push( info.Side, amtToMove );
			break;
		}
	}
	//Able to push the box
	//if(other.GetObjectID() == "Player")
	//{

	//	//Object that got hit
	//	LinecastInfo * ObjectHit = nullptr;

	//	//Box Width
	//	int BoxWidth = hitBox.right - hitBox.left;
	//	int BoxHeight = hitBox.bottom - hitBox.top;

	//	//Vectors
	//	tVector2D  RightCenterCheck = {hitBox.right + 1.0f, hitBox.top + (BoxHeight * 0.5f)};
	//	tVector2D  LeftCenterCheck = {hitBox.left - 1.0f, hitBox.top + (BoxHeight * 0.5f)};

	//	tVector2D CheckRight = {1,0};
	//	tVector2D CheckLeft = {-1,0};


	//	//Info to fill out
	//	/*LinecastInfo BoxToWall;

	//	if( Physics::LineCast(BoxToWall, 5, LeftCenterCheck, CheckLeft, "Player") )
	//	if(BoxToWall.GetObjectHit()->GetObjectID() == "Static Object")
	//	ObjectHit = &BoxToWall;*/


	//	//Check another side
	//	/*if( ObjectHit == nullptr )
	//	if( Physics::LineCast(BoxToWall, 5, RightCenterCheck, CheckRight, "Player") )
	//	if(BoxToWall.GetObjectHit()->GetObjectID() == "Static Object" )
	//	ObjectHit = &BoxToWall;*/

	//	if( ObjectHit == nullptr)
	//	{
	//		//Update the boxes collision
	//		if(info.Side == CollisionSide::BOTTOM)
	//			positionY += info.Overlap.bottom - info.Overlap.top;
	//		else if(info.Side == CollisionSide::TOP)
	//			positionY -= info.Overlap.bottom - info.Overlap.top;
	//		else if(info.Side == CollisionSide::LEFT)
	//			positionX -= info.Overlap.right - info.Overlap.left;
	//		else if(info.Side == CollisionSide::RIGHT)
	//			positionX += info.Overlap.right - info.Overlap.left;
	//	}
	//	if( ObjectHit != nullptr)
	//	{
	//		//Move the player if the box is hitting the wall

	//		if(info.Side == CollisionSide::BOTTOM)
	//			other.SetPosY( other.GetPosY() - (info.Overlap.bottom - info.Overlap.top));
	//		if(info.Side == CollisionSide::TOP)
	//			other.SetPosY( other.GetPosY() + (info.Overlap.bottom - info.Overlap.top));
	//		if(info.Side == CollisionSide::LEFT)
	//			other.SetPosX( other.GetPosX() + (info.Overlap.right - info.Overlap.left));
	//		if(info.Side == CollisionSide::RIGHT)
	//			other.SetPosX( other.GetPosX() - (info.Overlap.right - info.Overlap.left));

	//		//other.SetHitBox( Physics::UpdateColRect(other.GetHitBox(), other.GetPosX(), other.GetPosY()) );
	//	}


	//}

	if( other.GetTag() == "floor" )
	{
		canFall = false;
	}
	if (other.GetTag() == "ConveyorBelt")
	{
		canFall = false;
	}

	if( other.GetObjectID() == "Wood Box")
	{
		canFall = false;

		WoodBox* box = dynamic_cast<WoodBox*>(&other);

		if(box != nullptr)
			box->ApplyHeat(this->CurTemp());
	}
	else if(other.GetObjectID() == "Metal Box")
	{
		canFall = false;

		MetalBox* box = dynamic_cast<MetalBox*>(&other);

		if(box != nullptr)
			box->ApplyHeat(this->CurTemp());
	}
	else if(other.GetObjectID() == "Ice Layer")
	{
		IceLayer* ice = dynamic_cast<IceLayer*>(&other);

		if(ice != nullptr)
			ice->ApplyHeat(this->CurTemp());
	}
	else if(other.GetObjectID() == "Ice Block")
	{
		IceBlock* ice = dynamic_cast<IceBlock*>(&other);

		if(ice != nullptr)
			ice->ApplyHeat(this->CurTemp());
	}
	else if(other.GetObjectID() == "Water")
	{
		Water* water = dynamic_cast<Water*>(&other);

		if(water != nullptr)
			water->ApplyHeat(this->CurTemp());
	}

	if(other.GetObjectID() != "thermo object")
	{
	}

	if(other.GetObjectID() == "Button")
	{
		//canFall = false;
		//if(info.Side == CollisionSide::BOTTOM)
		//{
		//	positionY -= info.Overlap.bottom - info.Overlap.top;
		//}
		//else if(info.Side == CollisionSide::TOP)
		//{
		//	positionY += info.Overlap.bottom - info.Overlap.top;
		//}
		//else if(info.Side == CollisionSide::LEFT)
		//{
		//	positionX -= info.Overlap.right - info.Overlap.left;
		//}
		//else if(info.Side == CollisionSide::RIGHT)
		//{
		//	positionX += info.Overlap.right - info.Overlap.left;
		//}
		//else if(info.Side == CollisionSide::RIGHT)
		//{
		//	positionX -= info.Overlap.right - info.Overlap.left;
		//}

		//Physics::UpdateColRect(hitBox, (int)positionX, (int)positionY);
	}
	else
	{
		//if( other.GetTag() != "floor" && other.GetTag() != "thermo object" && other.GetTag() != "barrier")
		//{
		//	if(info.Side == CollisionSide::BOTTOM)
		//		positionY += info.Overlap.bottom - info.Overlap.top;
		//	else if(info.Side == CollisionSide::TOP)
		//		positionY -= info.Overlap.bottom - info.Overlap.top;
		//	else if(info.Side == CollisionSide::LEFT)
		//		positionX -= info.Overlap.right - info.Overlap.left;
		//	else if(info.Side == CollisionSide::RIGHT)
		//		positionX += info.Overlap.right - info.Overlap.left;
		//}

		//Physics::UpdateColRect(hitBox,positionX, positionY);

	}

	//Don't allow boxes to overlap eachother
	//if( other.GetObjectID() == "Wood Box" || other.GetObjectID() == "Metal Box")
	//{
	//	if(info.Side == CollisionSide::BOTTOM)
	//		positionY += info.Overlap.bottom - info.Overlap.top;
	//	if(info.Side == CollisionSide::TOP)
	//		positionY -= info.Overlap.bottom - info.Overlap.top;
	//	if(info.Side == CollisionSide::LEFT)
	//		positionX -= info.Overlap.right - info.Overlap.left;
	//	if(info.Side == CollisionSide::RIGHT)
	//		positionX += info.Overlap.right - info.Overlap.left;
	//}


}
void MetalBox::ResetToCheckPoint(void)
{
}
void MetalBox::ResetToStart(void)
{
}

void MetalBox::HandleEvent(Event* pEvent)
{
	if(pEvent->GetEventID() == "ApplyHeat")
	{
		GameObject* destination = (GameObject*) pEvent->GetDestination();
		if(destination == this)
		{
			float* temperatureChange = (float*)	pEvent->GetParam();
			ApplyHeat(*temperatureChange);
		}
	}
}


int MetalBox::Push(CollisionSide side, int amtToMove)
{
	LinecastInfo castInfo;
	tVector2D castStart;
	tVector2D castStartVert;
	tVector2D direction;
	switch(side)
	{
	case LEFT:
		castStart.fX = (float)hitBox.right;
		castStart.fY = positionY + (hitBox.bottom - hitBox.top)/2;
		direction.fX = 1;
		direction.fY = 0;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Metal Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionX += amtCanMove + 4;
			return amtCanMove;
		}
		else
		{
			positionX += amtToMove + 4;
			return amtToMove;
		}
		break;
	case RIGHT:
		castStart.fX = (float)hitBox.left;
		castStart.fY = positionY + (hitBox.bottom - hitBox.top)/2;
		direction.fX = -1;
		direction.fY = 0;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Metal Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionX -= amtCanMove + 4;
			return amtCanMove;
		}
		else
		{
			positionX -= amtToMove + 4;
			return amtToMove;
		}
		break;
	case TOP:
		castStart.fX = positionX + (hitBox.right - hitBox.left);
		castStartVert.fX = positionX;
		castStart.fY = (float)castStartVert.fY = (float)hitBox.top;
		direction.fX = 0;
		direction.fY = -1;
		if(Physics::LineCast(castInfo, (float)amtToMove, castStart,direction, "Metal Box") || Physics::LineCast(castInfo, (float)amtToMove, castStartVert,direction, "Metal Box"))
		{
			int amtCanMove = (int)castInfo.Distance;
			positionY += amtCanMove + 1;
			return amtCanMove;
		}
		else
		{
			positionY += (float)amtToMove + 1;
			return amtToMove;
		}
		break;
	case BOTTOM:
		//castStart.fX = positionX + (hitBox.right - hitBox.left);
		//castStartVert.fX = positionX;
		//castStart.fY = castStartVert.fY = hitBox.bottom;
		//direction.fX = 0;
		//direction.fY = 1;
		//if(Physics::LineCast(castInfo, amtToMove, castStart,direction, "Metal Box") || Physics::LineCast(castInfo, amtToMove, castStartVert,direction, "Metal Box"))
		//{
		//	int amtCanMove = castInfo.Distance;
		//	positionY += amtCanMove + 4;
		//	return amtCanMove;
		//}
		//else
		{
			positionY -= (float)amtToMove+ 1;
			return amtToMove;
		}
		break;
	}
	return 0;
}

